﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;

namespace PhoneTestApp
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
        private void buttonMedia_Click(object sender, RoutedEventArgs e)
        {
            // Find all Media Servers
            string item = "urn:schemas-upnp-org:device:MediaServer:1";

            // Disable button while scanning
            buttonMedia.IsEnabled = false;

            ScanNetwork(item, (newservice) =>
                {
                    if (newservice != null)
                    {
                        AddServiceToListAsync(newservice);
                        TestMediaBrowseAsync(newservice);
                    }
                    else
                    {
                        // Finished scan, so re-enable button
                        buttonMedia.IsEnabled = true;
                    }
                });
        }

        private void ScanNetwork(string item, Action<string> FoundCallback)
        {
            UPnP.Scanner finder = new UPnP.Scanner();

            finder.FindDevices(item, 3, (findresult) =>
            {
                Dispatcher.BeginInvoke(() =>
                {
                    if (findresult == null)
                    {
                        FoundCallback(null);
                    }
                    else
                    {
                        // Got a response
                        var newservice = UPnP.Scanner.GetSSDPLocation(findresult);
                        if (IsNewLocation(newservice))
                        {
                            FoundCallback(newservice);
                        }
                    }
                });
            });
        }

        async void TestMediaBrowseAsync(string uri)
        {
            var device = await UPnP.Device.Create_Async(uri);
            var contentdir = device.FindService("urn:upnp-org:serviceId:ContentDirectory");
            if (contentdir != null)
            {
                ContentDirectory cd = new ContentDirectory(contentdir);
                var cdresult = await cd.Browse("0", "BrowseMetadata", "*", (uint)0, (uint)1, "");

                Debug.WriteLine("Found device: " + device.FriendlyName);
                if (cdresult.Error == null)
                {
                    Debug.WriteLine("Number={0}, Total={1}, UpdateID={2}, Result={3}\n",
                        cdresult.NumberReturned,
                        cdresult.TotalMatches,
                        cdresult.UpdateID,
                        cdresult.Result);
                }
                else
                {
                    Debug.WriteLine("ERROR: {0} on BrowseMetadata call", cdresult.Error.Message);
                }
            }
        }

        private List<string> RootDevicesSoFar = new List<string>();

        // Have we seen this before?
        private bool IsNewLocation(string location)
        {
            if (location == null)
                return false;

            if (!RootDevicesSoFar.Contains(location))
            {
                RootDevicesSoFar.Add(location);
                return true;
            }
            else
            {
                return false;
            }
        }

        private void buttonAll_Click(object sender, RoutedEventArgs e)
        {
            string item = "upnp:rootdevice";           // all root devices

            buttonAll.IsEnabled = false;

            ScanNetwork(item, (findresult)=>
                {
                    if (findresult == null)
                    {
                        buttonAll.IsEnabled = true;
                    }
                    else
                    {
                        AddServiceToListAsync(findresult);
                    }
                });
        }

        async void AddServiceToListAsync(string uri)
        {
            var device = await UPnP.Device.Create_Async(uri);
            if (device != null)
            {
                textBlock1.Text += "\r\n" + device.FriendlyName;
            }
        }
    }
}